package com.happle.gcmclient;

import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gcm.GCMRegistrar;
import com.happle.gcmclient.adapter.StatusDialogAdapter;
import com.happle.gcmclient.backendmanager.BackendManager;
import com.happle.gcmclient.backendmanager.task.SendChangeStatusTask;
import com.happle.gcmclient.backendmanager.task.SendUnregisterTask;
import com.happle.gcmclient.config.CommonUtilities;
import com.happle.gcmclient.config.Constants;
import com.happle.gcmclient.config.GlobalValue;
import com.happle.gcmclient.service.SyncDataService;
import com.happle.gcmclient.utility.AlertDialogManager;
import com.happle.gcmclient.utility.DialogUtility;
import com.happle.gcmclient.utility.NetworkUtility;

public class BaseActivity extends Activity {

	protected final String TAG = this.getClass().getSimpleName();
	// Common variables
	protected AlertDialogManager alertManager;
	protected BaseActivity self;
	protected BackendManager backendManager;
	protected ProgressDialog progressDialog;
	protected String TAG_LOCAL = "";
	protected SendRegistrationTask registerTask;
	protected SendUnregisterTask unregisterTask;
	protected SendChangeStatusTask changeStatusTask;
	// Action bar var
	private TextView lblTitle;
    private ImageView lblTitleImage;
	private Button btnStatus;
    private ImageView btnStatusImage;
	private Button btnBack;
    private ImageView btnBackImage;
	private String[] items;
	private int[] itemsId;
    private ArrayList<Integer> btnStatusImages;
    private ArrayList<Integer> lblTitleImages;
    private AlertDialog dialog;

    @Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		self = this;
		alertManager = new AlertDialogManager();
		backendManager = new BackendManager();
	}

	protected void initHeader() {
		btnBack = (Button) findViewById(R.id.btnBack);
        btnBackImage = (ImageView) findViewById(R.id.btnBackImage);
		lblTitle = (TextView) findViewById(R.id.lblTitle);
        lblTitleImage = (ImageView)findViewById(R.id.lblTitleImage);
		btnStatus = (Button) findViewById(R.id.btnStatus);
        btnStatusImage = (ImageView)findViewById(R.id.btnStatusImage);
        // Status images init
        btnStatusImages = new ArrayList<Integer>();
        btnStatusImages.add(R.drawable.online_active);
        btnStatusImages.add(R.drawable.offline_active);
        btnStatusImages.add(R.drawable.invisible_active);
        // Title images init
        lblTitleImages = new ArrayList<Integer>();
        lblTitleImages.add(R.drawable.title_empty_image);
        lblTitleImages.add(R.drawable.title_conversations_image);
        lblTitleImages.add(R.drawable.title_messageslist_image);
        lblTitleImages.add(R.drawable.title_settings_image);

		btnBack.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				onBackHeaderClick();
			}
		});
		btnStatus.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				itemsId = getResources().getIntArray(R.array.arrStatusId);
				items = getResources().getStringArray(R.array.arrStatus);
//				DialogUtility.showSimpleOptionDialog(self, R.string.choose_option,
//                          items, null, onMenuItemClick, null);
                Integer[] images = new Integer[3];
                images[0] = Integer.valueOf(R.drawable.online);
                images[1] = Integer.valueOf(R.drawable.offline);
                images[2] = Integer.valueOf(R.drawable.invisible);
                showStatusDialog(items, images);
			}
		});
	}


    // status dialog
    public void showStatusDialog(String[] items, Integer[] images) {
        AlertDialog.Builder builder = new AlertDialog.Builder(self);
        LayoutInflater inflater = self.getLayoutInflater();
        View view= inflater.inflate(R.layout.status_dialog_layout_listview, null);

        builder.setView(view);
        ListView lv = (ListView)view.findViewById(R.id.statusDialogListview);
        StatusDialogAdapter statusAdapter = new StatusDialogAdapter(self, images, items);
        lv.setAdapter(statusAdapter);
        lv.setOnItemClickListener(onStatusMenuClick);

        TextView mainTitle = (TextView)view.findViewById(R.id.dialogMainTitle);
        mainTitle.setText(R.string.status_dialog_title);
        builder.setCustomTitle(null);
        lv.setDivider(null);
        builder.setPositiveButton(null, null);

        dialog = builder.create();
        dialog.show();
    }

    AdapterView.OnItemClickListener onStatusMenuClick = new AdapterView.OnItemClickListener(){

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            btnStatus.setText(items[position]);
            btnStatusImage.setImageResource(btnStatusImages.get(position));
            onChangeStatus(items[position], itemsId[position]);
            dialog.dismiss();
        }
    };

	protected void updateStatusTitle() {
		itemsId = getResources().getIntArray(R.array.arrStatusId);
		items = getResources().getStringArray(R.array.arrStatus);

		// 1: Online, 0: Offline, 2: Don't disturb
		int statusId = 0;
        Resources res = getResources();
		if (!CommonUtilities.getInstance(self)
				.getStringValue(Constants.IS_ONLINE).equalsIgnoreCase(""))
			statusId = Integer.parseInt(CommonUtilities.getInstance(self)
					.getStringValue(Constants.IS_ONLINE));
		if (statusId == 1){
			btnStatus.setText(items[0]);
            btnStatusImage.setImageResource(btnStatusImages.get(0));
        }
		else if (statusId == 0){
			btnStatus.setText(items[1]);
            btnStatusImage.setImageResource(btnStatusImages.get(1));
        }
		else if (statusId == 2){
			btnStatus.setText(items[2]);
            btnStatusImage.setImageResource(btnStatusImages.get(2));
        }
	}

	DialogInterface.OnClickListener onMenuItemClick = new DialogInterface.OnClickListener() {

		@Override
		public void onClick(DialogInterface dialog, int which) {
			btnStatus.setText(items[which]);
            btnStatusImage.setImageResource(btnStatusImages.get(which));
			onChangeStatus(items[which], itemsId[which]);
		}
	};

	protected void setHeaderTitle(String title, int imageNumber) {
		if (lblTitle != null){
			lblTitle.setText(title);
            lblTitleImage.setImageResource(lblTitleImages.get(imageNumber));
        }
	}

	protected void hideBack() {
		if (btnBack != null) {
			btnBack.setVisibility(View.GONE);
            btnBackImage.setVisibility(View.GONE);
            lblTitleImage.setVisibility(View.GONE);
        }
	}

	protected void onBackHeaderClick() {
		finish();
	}

	// U can call webservice here , to change user's status
	protected void onChangeStatus(String status_name, int status) {
		Toast.makeText(self, getResources().getText(R.string.status_changed) + status_name,
				Toast.LENGTH_LONG).show();
		proceedStatus(self, status);
	}

	public void showProgressDialog() {
		progressDialog = ProgressDialog.show(self,
				getString(R.string.app_name), getString(R.string.processing));
	}

	public void closeProgressDialog() {
		if (progressDialog != null && progressDialog.isShowing()) {
			progressDialog.dismiss();
			progressDialog.cancel();
			progressDialog = null;
		}
	}

	public void proceedStatus(Context context, int status) {
		int taskResult = -1;
		switch (status) {
		case Constants.STATUS_ON:
			try {

				changeStatusTask = new SendChangeStatusTask(
						GlobalValue.registerId, Constants.STATUS_ON);
				if (NetworkUtility.getInstance(self).isNetworkAvailable()) {
					changeStatusTask.execute();
					taskResult = changeStatusTask.get();
				}
				if (taskResult != -1)
					CommonUtilities.getInstance(self).savePreverences(self,
							Constants.IS_ONLINE,
							String.valueOf(Constants.STATUS_ON));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
//			registerClient();
			break;
		case Constants.STATUS_OFF:
			try {
				changeStatusTask = new SendChangeStatusTask(
						GlobalValue.registerId, Constants.STATUS_OFF);
				if (NetworkUtility.getInstance(self).isNetworkAvailable())
					changeStatusTask.execute();
				taskResult = changeStatusTask.get();
				if (taskResult != -1)
					CommonUtilities.getInstance(self).savePreverences(self,
							Constants.IS_ONLINE,
							String.valueOf(Constants.STATUS_OFF));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}

			// //I think we only just handle notification depend on user
			// status(See GCMIntentService line 63) don't need unregister and
			// register again when user change status
			// Un register GCM when status=off or disturb
			// unregisterGCM();
			break;

		case Constants.STATUS_INVISIBLE:
			try {
				changeStatusTask = new SendChangeStatusTask(
						GlobalValue.registerId, Constants.STATUS_INVISIBLE);
				if (NetworkUtility.getInstance(self).isNetworkAvailable())
					changeStatusTask.execute();
				taskResult = changeStatusTask.get();
				if (taskResult != -1)
					CommonUtilities.getInstance(self).savePreverences(self,
							Constants.IS_ONLINE,
							String.valueOf(Constants.STATUS_INVISIBLE));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
			// //I think we only just handle notification depend on user
			// status(See GCMIntentService line 63) don't need unregister and
			// register again when user change status
			// Un register GCM when status=off or disturb
			// unregisterGCM();

			break;
		}
	}

	private void unregisterGCM() {

		// I don't know why but after unregister , app still can receive
		// notification.
		// So i need check online status when message come in GCM intent to
		// display notification or not
		GCMRegistrar.unregister(self);
		GCMRegistrar.onDestroy(self);
		Intent unregIntent = new Intent(
				"com.google.android.c2dm.intent.UNREGISTER");
		unregIntent.putExtra(Constants.SENDER_ID,
				PendingIntent.getBroadcast(this, 0, new Intent(), 0));
		startService(unregIntent);

	}

	public void registerClient() {
		try {
			GCMRegistrar.checkDevice(this);
			GCMRegistrar.checkManifest(this);
			GlobalValue.registerId = GCMRegistrar.getRegistrationId(this);

			if (GlobalValue.registerId.equals("")) {
				// register this device for this project
				GCMRegistrar.register(this, Constants.SENDER_ID);

				GlobalValue.registerId = GCMRegistrar.getRegistrationId(this);
			} else {
				CommonUtilities.getInstance(self)
						.putStringValue(CommonUtilities.REGISTRATION_ID,
								GlobalValue.registerId);
			}
			CommonUtilities.getInstance(self).putStringValue(
					Constants.IS_ONLINE, String.valueOf(Constants.STATUS_ON));
		} catch (Exception e) {
			e.printStackTrace();
		}
		Log.d(TAG_LOCAL, GlobalValue.registerId);
	}

	public void hideKeyboard() {
		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
	}

	class SendRegistrationTask extends AsyncTask<Void, Void, Integer> {
		private String regId = "";
		private boolean isLogin = true;

		public SendRegistrationTask(Boolean IsLogin, String regId) {
			this.regId = regId;
			this.isLogin = IsLogin;
		}

		@Override
		protected Integer doInBackground(Void... params) {
			int result = Constants.FAILED;
			try {
				BackendManager bManager = new BackendManager();
				if (NetworkUtility.getInstance(self).isNetworkAvailable())
					result = bManager.sendLoginRegistration(regId, isLogin);
			} catch (Exception e) {
				e.printStackTrace();
			}
			Log.d(TAG_LOCAL, String.valueOf(result));
			return result;
		}

		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
		}
	}

	/**
	 * Start sync service
	 */
	protected void startSyncService() {
		if (!isSyncDataServiceRunning())
			startService(new Intent(this, SyncDataService.class));
		Log.d("SyncData", "Running :  " + isSyncDataServiceRunning());
	}

	/**
	 * Check if service sync data is running
	 * 
	 * @return
	 */
	private boolean isSyncDataServiceRunning() {
		ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
		for (RunningServiceInfo service : manager
				.getRunningServices(Integer.MAX_VALUE)) {
			// Log.d("ServiceRunning", service.service.getClassName());
			if (SyncDataService.class.getName().equals(
					service.service.getClassName())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Go to other activity
	 * 
	 * @param context
	 * @param cla
	 */
	public void gotoActivity(Context context, Class<?> cla) {
		Intent intent = new Intent(context, cla);
		startActivity(intent);
		// overridePendingTransition(R.anim.slide_in_left,
		// R.anim.slide_out_left);
	}

	public void gotoActivity(Context context, Class<?> cla, int flag) {
		Intent intent = new Intent(context, cla);
		intent.setFlags(flag);
		startActivity(intent);
		// overridePendingTransition(R.anim.slide_in_left,
		// R.anim.slide_out_left);
	}

	/**
	 * Go to other activity
	 * 
	 * @param context
	 * @param cla
	 */
	public void gotoActivityForResult(Context context, Class<?> cla,
			int requestCode) {
		Intent intent = new Intent(context, cla);
		startActivityForResult(intent, requestCode);
		// overridePendingTransition(R.anim.slide_in_left,
		// R.anim.slide_out_left);
	}

	/**
	 * Goto activity with bundle
	 * 
	 * @param context
	 * @param cla
	 * @param bundle
	 */
	public void gotoActivity(Context context, Class<?> cla, Bundle bundle) {
		Intent intent = new Intent(context, cla);
		intent.putExtras(bundle);
		startActivity(intent);
		// overridePendingTransition(R.anim.slide_in_left,
		// R.anim.slide_out_left);
	}

	/**
	 * Goto activity with bundle
	 * 
	 * @param context
	 * @param cla
	 * @param bundle
	 * @param requestCode
	 */
	public void gotoActivityForResult(Context context, Class<?> cla,
			Bundle bundle, int requestCode) {
		Intent intent = new Intent(context, cla);
		intent.putExtras(bundle);
		startActivityForResult(intent, requestCode);
	}

	// ======================= TOAST MANAGER =======================

	/**
	 * @param str
	 *            : alert message
	 * 
	 *            Show toast message
	 */
	public void showToastMessage(String str) {
		Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
	}

	/**
	 * @param strId
	 *            : alert message
	 * 
	 *            Show toast message
	 */
	public void showToastMessage(int strId) {
		Toast.makeText(this, getString(strId), Toast.LENGTH_LONG).show();
	}

	/**
	 * @param str
	 *            : alert message
	 * 
	 *            Show toast message
	 */
	public void showShortToastMessage(String str) {
		Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
	}

	public void showShortToastMessage(int str) {
		Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
	}

	/**
	 * @param str
	 *            : alert message
	 * 
	 *            Show toast message
	 */
	public void showToastMessage(String str, int time) {
		Toast.makeText(this, str, time).show();
	}

	/**
	 * @param : alert message
	 * 
	 *        Show toast message
	 */
	public void showToastMessage(int resId, int time) {
		Toast.makeText(this, resId, time).show();
	}

	/**
	 * Show comming soon toast message
	 */
	public void showComingSoonMessage() {
		showToastMessage("Coming soon!");
	}

	/**
	 * Goto web page
	 * 
	 * @param url
	 */
	public void gotoWebPage(String url) {

		if (!url.contains("http"))
			url = "http://" + url;
		Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
		startActivity(i);
	}

	/**
	 * Goto phone call
	 * 
	 * @param telNumber
	 */
	protected void gotoPhoneCallPage(String telNumber) {
		Intent i = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + telNumber));
		startActivity(i);
	}

    }
